/* Project includes */
#include "main.h"
//#include "TSC_2046.h"
#include "Hal_InputManagement.h"
#include "Hal_OutputManagement.h"
#include "Hal_PwmManagement.h"
#include "Hal_UsartManagement.h"


#ifdef _OSMOLATOR
    #include "osmolator.h"
#endif

#ifdef _CLOCK
    #include "clock.h"
#endif

#ifdef _TEMPERATURE
    #include "temperature.h"
#endif

#ifdef _LIGHT
    #include "light.h"
#endif

#ifdef _LEDSPWM
    #include "led.h"
#endif

#ifdef _OSCILLATOR
    #include "oscillator.h"
#endif

#ifdef _AFFICHAGE
    #include "affichage.h"
#endif

#ifdef _FAN
    #include "fan.h"
#endif

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */


/**
  * @brief  main(), contient tout les initialisations
  * @param  None
  * @retval : None
  */               
int main()
{
    prvSetupHardware();     /* Initialisation du materiel. */

    message_queue = xQueueCreate( 20, sizeof(__MESSAGE) );
    if ( message_queue == NULL )
    {
        NVIC_SystemReset();
    }

#ifdef _OSCILLATOR
    oscillateur_queue = xQueueCreate( 2, sizeof(Oscillator_def_t) );
    if ( oscillateur_queue == NULL )
    {
        NVIC_SystemReset();
    }
#endif /* _OSCILLATOR */

#ifdef _LIGHT
    light_queue = xQueueCreate( 2, sizeof(Light_def_t) );
    if ( light_queue == NULL )
    {
        NVIC_SystemReset();
    }
#endif /* _LIGHT */

#ifdef _LEDSPWM
    led_queue = xQueueCreate( 3, sizeof(Led_def_t) );
    if ( led_queue == NULL )
    {
        NVIC_SystemReset();
    } 
#endif /* _LEDSPWM */

#ifdef _CLOCK
    clock_queue = xQueueCreate( 2, sizeof(Clock_def_t) );
    if ( clock_queue == NULL )
    {
        NVIC_SystemReset();
    } 
#endif /* _CLOCK */

#ifdef _FAN
    fan_queue = xQueueCreate( 2, sizeof(Fan_def_t) );
    if ( fan_queue == NULL )
    {
        NVIC_SystemReset();
    } 
#endif /* _FAN */

    xTaskCreate( (void*)vTaskInit, (void*)"init", configMINIMAL_STACK_SIZE+2048, NULL, tskIDLE_PRIORITY+4, NULL );
    
    /* Start the scheduler. */
    vTaskStartScheduler();

    /* Will only get here if there was not enough heap space to create the
    idle task. */
    while(1);
        
    return 0;
}

/*
 *  Initialisation du materiel
 */
void vTaskInit()
{
    vTaskCTRL_InputManagementInit();
    vTaskCTRL_OutputManagementInit();
    vTaskCTRL_PwmManagementInit();
    vTaskCTRL_UsartManagementInit();
   
    //TSC2046_Init();
    
    // initialisation de la sd card
    if ( SD_Config() != 0 )
    {
        printf("SDcard not present");
    }

    xTaskCreate( (void*)vTaskCTRL, (void*)"CTRL", configMINIMAL_STACK_SIZE+512, NULL, tskIDLE_PRIORITY+4, NULL );
   
    vTaskDelete(NULL);
}
/*
 *  Demarrage du controleur general
 */
void vTaskCTRL()
{
    portTickType xLastWakeTime;
    xLastWakeTime = xTaskGetTickCount();
    char date[80];
    __MESSAGE message;
    // demarrage de tous les modules
    
    //
    // module horloge ( gestion heure, calendrier )
    //
    #ifdef _CLOCK
        xTaskCreate( (void*)vTaskCTRL_TIME, (void*)"time", configMINIMAL_STACK_SIZE+512, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_TIME );
    #endif 

    //
    // module osmolator    ( gestion sonde niveau, pompe )
    //
    #ifdef _OSMOLATOR
        xTaskCreate( (void*)vTaskCTRL_OSMOLATOR, (void*)"osmolator", configMINIMAL_STACK_SIZE+128, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OSMOLATOR );
    #endif

    //
    // module temperature  ( gestion sonde, ventillateur, chauffage )
    //
    #ifdef _TEMPERATURE
        xTaskCreate( (void*)vTaskCTRL_TEMPERATURE, (void*)"temp", configMINIMAL_STACK_SIZE+512, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_TEMP );
    #endif
        
    //
    // module eclairage ( gestion eclairage )
    //
    #ifdef _LIGHT
        #ifdef _CLOCK
            xTaskCreate( (void*)vTaskCTRL_ECLAIRAGE, (void*)"eclairage", configMINIMAL_STACK_SIZE+128, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_LIGHT );
        #endif
    #endif
    
    #ifdef _LEDSPWM
        #ifdef _CLOCK
            xTaskCreate( (void*)vTaskCTRL_INTERPOLATED_LEDS_PWM, (void*)"LED", configMINIMAL_STACK_SIZE+256, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_LEDSPWM );
        #endif
    #endif
    
    //
    // module PHmetre ( gestion de la sonde PH )
    //
    #ifdef _PHMETRE
    
    #endif
            
    //
    // module oscilateur ( gestion de l'oscillation des pompes )
    //
    #ifdef _OSCILLATOR
        xTaskCreate( (void*)vTaskCTRL_OSCILLATOR, (void*)"oscillator", configMINIMAL_STACK_SIZE+256, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OSCILLATOR );
    #endif
    
    //
    // module ventilateur ( gestion des ventilateurs )
    //
    #ifdef _FAN
        xTaskCreate( (void*)vTaskCTRL_FAN, (void*)"fan", configMINIMAL_STACK_SIZE+256, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_FANS );
    #endif
        
    //
    // module affichage
    //   
    #ifdef _AFFICHAGE
        xTaskCreate( (void*)vTaskCTRL_AFFICHAGE, (void*)"affichage", configMINIMAL_STACK_SIZE+2048, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_AFFICHAGE );
    #endif
       
    // boucle principale, controle tous les modules principaux
    while(1)
    {  
        // controle de la file de message
        if ( uxQueueMessagesWaiting( message_queue ) > 0 )
        {
            xQueueReceive( message_queue, &message, 10); 
        
            getTime(date);
        
            switch(message.priority)
            {
              case alert:
              {
                printf("%s : message alert : %s\r\n", date, message.message);
                break;
              }
              case warning:
              {
                printf("%s : message warning : %s\r\n", date, message.message);
                break;
              }
              case normal:
              {
                printf("%s : message normal : %s\r\n", date, message.message);
                break;
              }
              default:
              {
                printf("%s : message inconnu : %s\r\n", date, message.message);
                break;
              }
            }
        }
    
        /* Reload watchdog each second              */
        /* If watchdog is not reload, a reset occur */
        //WWDG_SetCounter(127);
    
        wait(1000);
    }
}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

// envoi un message dan la file
void send_message(uint8_t task_id, _MESSAGE_PRIORITY priority, char *message)
{
    portTickType xLastWakeTime;
    xLastWakeTime = xTaskGetTickCount();
    __MESSAGE q_message = {0, 0, ""};

    q_message.task_id = task_id;
    q_message.priority = priority;
    strcpy( q_message.message, message);
    xQueueSendToBack( message_queue, &q_message, 0);
    wait(10);
}

